package com.chart;

import android.graphics.Color;
import android.os.Bundle;
import android.util.SparseArray;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;

import com.me.bean.Xy;
import com.me.blood.databinding.FragChart2Binding;
import com.me.blood.frag.BaseFragment;
import com.me.utils.Utils;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;

import lecho.lib.hellocharts.listener.LineChartOnValueSelectListener;
import lecho.lib.hellocharts.model.Axis;
import lecho.lib.hellocharts.model.AxisValue;
import lecho.lib.hellocharts.model.Line;
import lecho.lib.hellocharts.model.LineChartData;
import lecho.lib.hellocharts.model.PointValue;
import lecho.lib.hellocharts.model.SelectedValue;
import lecho.lib.hellocharts.model.ValueShape;
import lecho.lib.hellocharts.model.Viewport;
import lecho.lib.hellocharts.view.LineChartView;

public class Chart3Fragment extends BaseFragment {

    FragChart2Binding binding;

    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        binding = FragChart2Binding.inflate(inflater, container, false);
        initChart();
        setData();
        return binding.getRoot();
    }

    void initChart() {

        binding.chart.setZoomEnabled(false);
        binding.chart.setScrollEnabled(false);

        binding.chart.setValueSelectionEnabled(true);
        binding.chart.setOnValueTouchListener(new LineChartOnValueSelectListener() {

            @Override
            public void onValueDeselected() {

            }

            @Override
            public void onValueSelected(int lineIndex, int pointIndex, PointValue value) {
                if (listener != null) {
                    listener.onValueSelected(lineIndex, pointIndex, value);
                }
            }
        });
    }

    List<Xy> list;
    LineChartOnValueSelectListener listener;
    int type;
    String date;

    public void setData(List l, int type, String date, LineChartOnValueSelectListener listener) {
        list = l;
        this.date = date;
        this.type = type;
        this.listener = listener;
    }

    public String getLabel(int key) {
        String s;
        try {
            s = String.valueOf(binding.chart.getLineChartData().getAxisXBottom().getValues().get(key).getLabel());
        } catch (Throwable e) {
            s = "--";
        }
        return s;
    }

    private void setData() {
        if (list == null) {
            return;
        }
        ArrayList<PointValue> values = new ArrayList<>();
        float maxPoint = 0, minPoint = Float.MAX_VALUE;
        if (type == 0) {
            for (Xy item : list) {
                Calendar c = Calendar.getInstance();
                c.setTimeInMillis(item.time);
                int h = c.get(Calendar.HOUR_OF_DAY);
                int min = c.get(Calendar.MINUTE);
                float time = h + min / 60f;
                values.add(new PointValue(time, item.high).setTag(item));
                values.add(new PointValue(time, item.low).setTag(item));
                if (item.low < minPoint) {
                    minPoint = item.low;
                }
                if (item.high > maxPoint) {
                    maxPoint = item.high;
                }
            }
        } else if (type == 1) {
            SparseArray<Xy> array = new SparseArray();
            float high = 0, low = 0;
            int count = 0;
            String day = null;
            for (Xy item : list) {
                if (item.high > maxPoint) {
                    maxPoint = item.high;
                }
                if (item.low < minPoint) {
                    minPoint = item.low;
                }
                String d = Utils.getDay(item.time);
                if (d.equals(day)) {
                    ++count;
                    high += item.high;
                    low += item.low;
                } else {
                    if (day != null) {
                        long time = Utils.date2Ms(day);
                        Calendar c = Calendar.getInstance();
                        c.setTimeInMillis(time);
                        int index = c.get(Calendar.DAY_OF_WEEK);
                        Xy tmp = new Xy();
                        tmp.high = (int) (high / count);
                        tmp.low = (int) (low / count);
                        array.put(index, tmp);
                    }
                    day = d;
                    count = 1;
                    high = item.high;
                    low = item.low;
                    long time = Utils.date2Ms(day);
                    Calendar c = Calendar.getInstance();
                    c.setTimeInMillis(time);
                    int index = c.get(Calendar.DAY_OF_WEEK);
                    Xy tmp = new Xy();
                    tmp.high = (int) high;
                    tmp.low = (int) low;
                    array.put(index, tmp);
                }
            }
            for (int i = 0; i < array.size(); i++) {
                int key = array.keyAt(i);
                Xy item = array.get(key);
                values.add(new PointValue(key, item.high).setTag(item));
                values.add(new PointValue(key, item.low).setTag(item));
            }
        } else if (type == 2) {
            SparseArray<Xy> array = new SparseArray();
            float high = 0, low = 0;
            int count = 0;
            String day = null;
            for (Xy item : list) {
                if (item.high > maxPoint) {
                    maxPoint = item.high;
                }
                if (item.low < minPoint) {
                    minPoint = item.low;
                }
                String d = Utils.getDay(item.time);
                if (d.equals(day)) {
                    ++count;
                    high += item.high;
                    low += item.low;
                } else {
                    if (day != null) {
                        long time = Utils.date2Ms(day);
                        Calendar c = Calendar.getInstance();
                        c.setTimeInMillis(time);
                        int index = c.get(Calendar.DAY_OF_MONTH);
                        Xy tmp = new Xy();
                        tmp.high = (int) (high / count);
                        tmp.low = (int) (low / count);
                        array.put(index, tmp);
                    }
                    day = d;
                    count = 1;
                    high = item.high;
                    low = item.low;
                    long time = Utils.date2Ms(day);
                    Calendar c = Calendar.getInstance();
                    c.setTimeInMillis(time);
                    int index = c.get(Calendar.DAY_OF_MONTH);
                    Xy tmp = new Xy();
                    tmp.high = (int) high;
                    tmp.low = (int) low;
                    array.put(index, tmp);
                }
            }
            for (int i = 0; i < array.size(); i++) {
                int key = array.keyAt(i);
                Xy item = array.get(key);
                values.add(new PointValue(key, item.high).setTag(item));
                values.add(new PointValue(key, item.low).setTag(item));
            }
        }
        test(values, binding.chart, minPoint, maxPoint);
//        //In most cased you can call data model methods in builder-pattern-like manner.
//        Line line = new Line(values).setColor(Color.BLUE);//.setCubic(true);
//        List<Line> lines = new ArrayList<Line>();
//        lines.add(line);
//
//        LineChartData data = new LineChartData();
//        data.setLines(lines);
//        Axis axisX = new Axis();
//        Axis axisY = new Axis().setHasLines(true);
//        axisX.setName("Axis X");
//        axisX.setAutoGenerated(true);
//        axisY.setName("Axis Y");
//        axisY.setAutoGenerated(true);
//        data.setAxisXBottom(axisX);
//        data.setAxisYLeft(axisY);
//
//        binding.chart.setLineChartData(data);
//
//        Viewport v = new Viewport(binding.chart.getMaximumViewport());
//        //Y轴最大值为 加上20、防止显示不全
//        v.top = maxPoint + 5;
//        //最小值 Y轴最低点就为0
//        if (minPoint - 100 < 0) {
//            v.bottom = 0;
//        } else {
//            v.bottom = minPoint - 100;//最小值
//        }
//        //设置最大化的viewport （chartdata）后再调用
//        //这2个属性的设置一定要在lineChart.setMaximumViewport(v);这个方法之后,不然显示的坐标数据是不能左右滑动查看更多数据的
//        binding.chart.setMaximumViewport(v);
    }

    private void test(ArrayList<PointValue> mPointValues, LineChartView lineChartView, float minPoint, float maxPoint) {
        Line line = new Line(mPointValues);
        //存放线条的集合
        List<Line> lines = new ArrayList<>();
        //LineChartValueFormatter chartValueFormatter = new SimpleLineChartValueFormatter(2);
        //line.setFormatter(chartValueFormatter);//显示小数点（后2位）
//        line.setHasLabels(true);//曲线的数据坐标是否加上备注
//        line.setHasLabelsOnlyForSelected(true);//点击数据坐标提示数据（设置了这个line.setHasLabels(true);就无效）
        line.setShape(ValueShape.CIRCLE);//折线图上每个数据点的形状 这里是圆形 （
        //有三种 ：ValueShape.SQUARE(方形)  ValueShape.CIRCLE(圆形)  ValueShape.DIAMOND (菱形)）
        line.setPointRadius(3);//坐标点大小
        line.setCubic(false);//曲线是否平滑
        line.setFilled(false);//是否填充曲线的面积
        line.setHasLines(false);//是否用直线显示。如果为false 则没有曲线只有点显示
        line.setHasPoints(true);//是否显示圆点 如果为false 则没有原点只有点显示
        line.setColor(Color.parseColor("#aa0FB7A2"));
        line.setStrokeWidth(1);//设置线的宽度
        lines.add(line);

        LineChartData lineChartData = new LineChartData();
        lineChartData.setLines(lines);
        //设置数据的初始值，即所有的数据从baseValue开始计算，默认值为0。
        lineChartData.setBaseValue(0f);
        Axis axisX = new Axis();
        Axis axisY = new Axis().setHasLines(true);

        //设置x轴的坐标
//        axisX.setValues(mAxisXValues);
//        axisX.setHasTiltedLabels(true);
        //设置Y轴的坐标
//            axisY.setValues(mLineAxisYValues);//手动填充纵坐标数据

        int days = 0;
        if (type == 1) {
            List<AxisValue> mAxisYValues = new ArrayList<AxisValue>();
            mAxisYValues.add(new AxisValue(1).setLabel("周日"));
            mAxisYValues.add(new AxisValue(2).setLabel("周一"));
            mAxisYValues.add(new AxisValue(3).setLabel("周二"));
            mAxisYValues.add(new AxisValue(4).setLabel("周三"));
            mAxisYValues.add(new AxisValue(5).setLabel("周四"));
            mAxisYValues.add(new AxisValue(6).setLabel("周五"));
            mAxisYValues.add(new AxisValue(7).setLabel("周六"));
            axisX.setValues(mAxisYValues);
        } else if (type == 2) {
            Calendar c = Calendar.getInstance();
            c.setTimeInMillis(Utils.date2Ms(date));
            int m = c.get(Calendar.MONTH) + 1;
            List<AxisValue> mAxisYValues = new ArrayList<AxisValue>();
            days = c.getActualMaximum(Calendar.DAY_OF_MONTH);
            for (int i = 0; i < days; i++) {
                mAxisYValues.add(new AxisValue(i + 1).setLabel(m + "/" + (i + 1)));
            }
            axisX.setValues(mAxisYValues);
        }
//        for(int i=0; i<18; i++){
//            mAxisYValues.add(new AxisValue(i).setLabel("" + i));
//        }
//        axisY.setValues(mAxisYValues);
//        axisY.setHasTiltedLabels(true);
//        axisY.setAutoGenerated(true);//自定义纵坐标数据
//        axisY.setInside(true);//坐标数据显示在内测
        lineChartData.setAxisXBottom(axisX);
        lineChartData.setAxisYLeft(axisY);

        lineChartView.setZoomEnabled(false);//是否支持缩放
        lineChartView.setValueSelectionEnabled(true);//设置是否可以选中图表中的值，即当点击图表中的数据值后，会一直处于选中状态，直到用户点击其他空间。默认为false。
        lineChartView.setLineChartData(lineChartData);

        SelectedValue tmp = new SelectedValue();
        tmp.set(0, mPointValues.size() - 1, null);
        lineChartView.selectValue(tmp);


        final Viewport v = new Viewport(lineChartView.getMaximumViewport());
        v.left = 0;
        if (type == 0) {
            v.right = 24;
        } else if (type == 1) {
            v.right = 8;
        } else if (type == 2) {
            v.right = days + 1;
        }
        v.top = maxPoint + 10;
        v.bottom = Math.max(0, minPoint - 10);
        lineChartView.setMaximumViewport(v);
        lineChartView.setCurrentViewport(v);
    }
}
